<script setup>
import {
  computed,
  reactive,
  ref,
  watch,
  createVNode,
  defineProps
} from "vue";
import {
  SearchOutlined,
  DeleteOutlined,
  ExclamationCircleOutlined,
  RedoOutlined,
  QuestionCircleOutlined,
} from "@ant-design/icons-vue";
import store from "@/store";
import request, { errorHandler } from "@/common/utils/request";
import defaultSetting from "@/common/utils/defaultSetting";

import InputQA from "./components/InputQA/index.vue";
import InputDoc from "./components/InputDoc/index.vue";

import emptyQa from "./static/empty-qa.png";
import emptyDoc from "./static/empty-doc.png";
import { Modal, message } from "ant-design-vue";
import { debounce } from "lodash";

const props = defineProps({
    wikiId: {
      type: Number,
      required: true,
    }
})

const formatBytes = (a, b) => {
  if (0 == a) return "0 B";
  var c = 1024,
    d = b || 2,
    e = ["字符", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"],
    f = Math.floor(Math.log(a) / Math.log(c));
  return parseFloat((a / Math.pow(c, f)).toFixed(d)) + " " + e[f];
};

const uploadResponse = (response) => {
  const { code } = response;
  if (code === 1000) {
    return Promise.resolve(response.data);
  } else {
    return errorHandler({ data: response });
  }
};

let baseUrl = defaultSetting.requestDomain;
if (process.env.NODE_ENV === "development") {
  baseUrl = baseUrl + "/api";
}

const emptyData = {
  qa: {
    text: "录入问答",
    icon: emptyQa,
  },
  document: {
    text: "录入文档",
    icon: emptyDoc,
  },
};

const btnData = {
  qa: {
    text: "录入问答",
  },
  document: {
    text: "录入文档",
  },
};

const columns = [
  {
    title: "id",
    dataIndex: "id",
    width: 100,
  },
  {
    title: "文件名",
    dataIndex: "title",
    slots: { customRender: 'title' },
  },
  {
    title: "格式",
    dataIndex: "type",
    width: 70,
  },
  {
    title: "大小字符数",
    dataIndex: "raw_size",
    width: 150,
    slots: { customRender: 'raw_size' },
  },
  {
    title: "学习状态",
    dataIndex: "status_text",
    width: 150,
    align: "center",
  },
  {
    title: "创建时间",
    dataIndex: "created_at",
    width: 180,
  },
  {
    title: "操作",
    dataIndex: "action",
    width: 180,
    align: "left",
    fixed: "right",
    slots: { customRender: 'action' },
  },
];

const activeKey = ref("qa"); // qa问答集 doc文档集
const dataSource = ref([]);
const tableLoading = ref(false);
const isSearchInput = ref(false);
const isBatchAction = ref(false);

const InputQAVisible = ref(false);
const InputDocVisible = ref(false);
const timedTaskVisible = ref(false);

const state = reactive({
  keywords: "",
  page: 1,
  pageSize: 10,
  total: 0,
  dataInfo: {},
  refresh_switch: 0,
});

const pagination = computed(() => ({
  total: state.total,
  current: state.page,
  pageSize: state.pageSize,
  showSizeChanger: true,
}));

const selectedRowKeys = ref([]);
const selectedRows = ref([]);
const reTimer = ref(null);

const getWikiData = (init, loading = true) => {
  reTimer.value && clearTimeout(reTimer.value)

  tableLoading.value = loading;

  if (init) {
    state.page = 1;
  }

  let params = {
    page: state.page,
    pageSize: state.pageSize,
    wiki_id: props.wikiId,
    business_type: activeKey.value === "qa" ? "qa" : "document",
  };
  if (state.keywords) {
    params.keywords = state.keywords;
  }

  request
    .get("/work_ai", "/user/knowledge/document/files", params)
    .then((res) => {
      state.total = res.total;
      dataSource.value = res.list;
      tableLoading.value = false;

      for(let data of res.list){
        if(data.status == 'learning' || data.status == 'parsing'){
          reTimer.value = setTimeout(() => {
            getWikiData(false, false);
          }, 5000)

          break;
        }
      }
    })
    .catch(() => {
      dataSource.value = [];
      tableLoading.value = false;
    });
};

watch(
  () => state.keywords,
  debounce(() => {
    getWikiData(true);
  }, 300)
);

watch(
  () => activeKey.value,
  () => {
    getWikiData(true);
  }
);

const handleTableChange = (pager) => {
  state.page = pager.current;
  state.pageSize = pager.pageSize;
  getWikiData();
};

const handleChangeRowSelection = (keys, rows) => {
  selectedRowKeys.value = keys;
  selectedRows.value = rows;
  console.log(selectedRowKeys.value, selectedRows.value);
};

const handleEdit = (item, flag) => {
  state.dataInfo = {
    ...item,
    wiki_id: props.wikiId,
  };

  // 配置定时任务
  if (flag === "task") {
    state.refresh_switch = item.refresh_switch;
    timedTaskVisible.value = true;
    return;
  }

  // 录入问答或文档
  if (activeKey.value === "qa") {
    InputQAVisible.value = true;
  } else {
    InputDocVisible.value = true;
  }
};

// 设置定时刷新
const handleSetTimedTask = () => {
  request
    .post("/work_ai", "/user/knowledge/document/refresh_switch", {
      id: state.dataInfo?.id,
      refresh_switch: state.refresh_switch,
    })
    .then((res) => {
      timedTaskVisible.value = false;
      state.dataInfo = {};
      state.refresh_switch = 0;
      getWikiData(true);
    });
};

// 导入excel
const importCsvUploadChange = ({ file }, item) => {
  state.dataInfo = {
    ...item,
    wiki_id: props.wikiId,
  };
  if (file.status === "uploading") {
    return;
  }

  if (file.status === "done") {
    uploadResponse(file.response).then(({ data }) => {
      request
        .post("/work_ai", "/user/knowledge/document/delete", {
          id: state.dataInfo?.id,
        })
        .then((res) => {
          state.dataInfo = {};
          getWikiData(true);
        });
    });
  }

  if (file.status === "error") {
    message.error("上传失败");
  }
};

const handleDel = (id) => {
  Modal.confirm({
    title: "确认删除",
    content: "删除后将影响机器人的训练结果，不可恢复！",
    icon: () => createVNode(ExclamationCircleOutlined),
    centered: true,
    okText: "确定",
    cancelText: "取消",
    onOk: () => {
      request
        .post("/work_ai", "/user/knowledge/document/delete", {
          id,
        })
        .then((res) => {
          message.success("删除成功");
          getWikiData(true);
        });
    },
  });
};

// 批量删除
const handleBatchDel = () => {};

const handleRefresh = () => {
  getWikiData();
};

const handleOpenVisible = () => {
  if (activeKey.value === "qa") {
    InputQAVisible.value = true;
  } else {
    InputDocVisible.value = true;
  }
};

const handleCancel = (refresh) => {
  state.dataInfo = {};
  if (refresh) {
    getWikiData();
  }
  if (activeKey.value === "qa") {
    InputQAVisible.value = false;
  } else {
    InputDocVisible.value = false;
  }
};

const init = () => {
  getWikiData(true)
};

init();
</script>

<template>
  <div class="knowledge-base-wrap flex flex-col overflow-hidden h-full">
    <div class="base-tab">
      <a-tabs v-model:activeKey="activeKey" type="card">
        <a-tab-pane key="qa" tab="问答集"> </a-tab-pane>
        <a-tab-pane key="document" tab="文档集"> </a-tab-pane>
      </a-tabs>
      <div class="action-group">
        <a-space :size="16">
          <a-button type="default" @click="handleRefresh">
            <a-space>
              <RedoOutlined />
              刷新
            </a-space>
          </a-button>
          <!-- <a-button type="default" @click="isBatchAction = !isBatchAction"
            >批量操作</a-button
          > -->
          <a-button
            type="default"
            v-if="!isSearchInput"
            @click="isSearchInput = true"
          >
            <SearchOutlined />
          </a-button>
          <a-input
            v-if="isSearchInput"
            style="width: 200px"
            allowClear
            autofocus
            @blur="
              () => {
                if (!state.keywords) {
                  isSearchInput = false;
                }
              }
            "
            v-model:value="state.keywords"
          >
            <template #addonBefore> <SearchOutlined /> </template
          ></a-input>

          <a-button
            :disabled="selectedRowKeys?.length === 0"
            v-if="isBatchAction"
            type="link"
            @click="handleBatchDel"
            ><a-space> <DeleteOutlined /> 删除 </a-space>
          </a-button>
          <a-button type="primary" @click="handleOpenVisible">{{
            btnData[activeKey].text
          }}</a-button>
        </a-space>
      </div>
    </div>
    <div class="base-content flex-1 overflow-y-auto">
      <a-table
        v-if="dataSource?.length !== 0"
        :loading="tableLoading"
        :dataSource="dataSource"
        :columns="columns"
        :scroll="{ x: 1300 }"
        @change="handleTableChange"
        :pagination="pagination"
        rowKey="id"
        :rowSelection="
          isBatchAction
            ? {
                type: 'checkbox',
                selectedRowKeys: selectedRowKeys,
                onChange: handleChangeRowSelection,
              }
            : null
        "
      >
          <template #title="{ record }">
            <div class="beauty-scroller-bar" style="max-height: 200px; overflow: hidden auto; padding-right: 10px;">
              {{ record?.title }}
            </div>
          </template>
          <template #raw_size="{ record }">
            {{ formatBytes(record?.raw_size, 1) }}
          </template>
          <template #action="{ record }">
            <template v-if="activeKey === 'qa'">
              <a-space style="flex-flow: wrap;">
                <a-button
                  v-if="record.type === 'text'"
                  type="link"
                  @click="handleEdit(record)"
                  style="padding: 0px"
                  :disabled="record.status == 'learning'"
                  >编辑</a-button
                >
                <a-upload
                  name="file"
                  v-if="record.type !== 'text'"
                  accept=".xls,.xlsx"
                  :multiple="false"
                  :action="`${baseUrl}/work_ai/user/knowledge/document/qa/upload`"
                  :showUploadList="false"
                  @change="(file) => importCsvUploadChange(file, record)"
                  :data="{
                    user_token: $utils.getToken(),
                    wiki_id: wikiId,
                    org_id: $utils.getOrgId(),
                    team_id: $utils.getCurrentTeam(),
                  }"
                >
                  <a-button type="link" style="padding: 0px">替换</a-button>
                </a-upload>
                <a-button type="link" danger @click="handleDel(record.id)" style="padding: 0px"
                  >删除</a-button
                >
              </a-space>
            </template>
            <template v-if="activeKey === 'document'">
              <!-- <a-button v-if="record?.status === 0" type="link">重试</a-button> -->
              <a-space  style="flex-flow: wrap;">
                <a-upload
                  name="file"
                  v-if="record.type !== 'text' && record.type !== 'url'"
                  accept=".pdf,.docx,.txt,.md,.jpg,.jpeg,.png,.mp3,.mp4,.m4a,.wav"
                  :multiple="true"
                  :action="`${baseUrl}/work_ai/user/knowledge/document/upload`"
                  :showUploadList="false"
                  @change="(file) => importCsvUploadChange(file, record)"
                  :data="{
                    user_token: $utils.getToken(),
                    wiki_id: wikiId,
                    org_id: $utils.getOrgId(),
                    team_id: $utils.getCurrentTeam(),
                  }"
                >
                  <a-button type="link" style="padding: 0px" :disabled="record.status == 'learning' || record.status == 'parsing'">替换</a-button>
                </a-upload>
                <a-button
                  v-if="record?.type === 'text' || record?.type === 'url'"
                  type="link"
                  @click="handleEdit(record)"
                  style="padding: 0px"
                  :disabled="record.status == 'learning'"
                  >编辑</a-button
                >
                <!-- <a-button
                  type="link"
                  disabled
                  style="padding: 0px"
                  >生成问答</a-button
                > -->
                <a-button
                  v-if="record.type === 'url'"
                  type="link"
                  @click="handleEdit(record, 'task')"
                  style="padding: 0px"
                  >配置定时任务</a-button
                >
                <a-button type="link" danger @click="handleDel(record.id)" style="padding: 0px"
                  >删除</a-button
                >
              </a-space>
            </template>
          </template>
      </a-table>
      <div v-if="dataSource?.length === 0" class="no-data">
        <img :src="emptyData[activeKey].icon" />
        <div class="no-data-desc">
          您还没有录入{{ emptyData[activeKey].text }}，快去录入吧！
        </div>
        <a-button type="default" @click="handleOpenVisible">{{
          emptyData[activeKey].text
        }}</a-button>
      </div>
    </div>

    <a-modal
      :width="490"
      @cancel="
        () => {
          state.dataInfo = {};
          timedTaskVisible = false;
        }
      "
      @ok="handleSetTimedTask"
      v-model:visible="timedTaskVisible"
      title="配置定时任务"
    >
      <a-form-item>
        <template #label>
          <a-space>
            定时刷新
            <a-tooltip
              placement="right"
              title="开启后，将于每周一 03:00 定时再次学习当前网页内容。"
            >
              <QuestionCircleOutlined /> </a-tooltip
          ></a-space>
        </template>
        &nbsp;&nbsp;
        <a-switch
          :unCheckedValue="0"
          :checkedValue="1"
          v-model:checked="state.refresh_switch"
          unCheckedChildren="关闭"
          checkedChildren="开启"
        ></a-switch>
      </a-form-item>
    </a-modal>

    <InputQA
      :data="{ ...state.dataInfo, wiki_id: wikiId }"
      :visible="InputQAVisible"
      @cancel="handleCancel"
    />

    <InputDoc
      :data="{ ...state.dataInfo, wiki_id: wikiId }"
      :visible="InputDocVisible"
      @cancel="handleCancel"
    />
  </div>
</template>

<style lang="less" scoped>
.knowledge-base-wrap {
  /deep/ .ant-table-title {
    display: none;
  }

  .base-tab {
    position: relative;

    .action-group {
      padding: 0;
      position: absolute;
      right: 0;
      top: 5px;
    }

    :deep(.ss-tabs-nav-list) {
      padding: 4px;
      background: #f0f0f0;
      border-radius: 12px !important;

      .ss-tabs-tab {
        background: transparent;
        padding: 6px 16px;
        border-radius: 8px !important;
        border: none !important;
        color: #596780;
      }
      .ss-tabs-tab-active {
        background: #fff;
        color: var(--ss-primary-color);
      }
    }

    :deep(.ss-tabs-nav) {
      &::before {
        display: none;
      }
    }
  }

  .base-content {
    :deep(.ss-table-tbody) {
      .ss-table-cell {
        padding: 10px 16px;
      }
    }
    .no-data {
      margin-top: 150px;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;

      img {
        width: 332px;
        height: 196px;
      }

      .no-data-desc {
        margin: 48px 0 24px;
        font-size: 12px;
        color: #9da3af;
      }
    }
  }
}
</style>
